package com.wen.apiinterfacemock.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wen.apiinterfacemock.service.JsonCompareService;
import org.springframework.stereotype.Service;

import java.util.Iterator;
import java.util.Map;


public class JsonCompareServiceImpl implements JsonCompareService {


    /**
     * 比较两个 JsonNode 对象，找出它们的差异。
     * @param oldNode 要比较的第一个 JsonNode 对象
     * @param newNode 要比较的第二个 JsonNode 对象
     *
     * @return 包含两个 JsonNode 对象差异的 JsonNode 对象
     */
    public JsonNode compare(JsonNode oldNode, JsonNode newNode) {
        ObjectMapper mapper = new ObjectMapper();
        // 创建一个空的 JSON 对象，用于存储差异结果
        ObjectNode resultNode = mapper.createObjectNode();

        //空情况，即 master 和 branch 两个环境比较结果有数量差异，直接返回 null 字段
        if(oldNode == null || newNode == null) {
            // 如果任一节点为 null，将其包含在 diff 结果中
            if (oldNode == null) {
                ObjectNode diffNode = resultNode.putObject("value");
                diffNode.set("oldNode", null);
                return diffNode;
            } else {
                ObjectNode diffNode = resultNode.putObject("value");
                diffNode.set("newNode", null);
                return diffNode;
            }
        }else if (oldNode.isObject() && newNode.isObject()) {
            // 判断 oldNode 和 newNode 是否都为对象类型
            // 迭代 oldNode 中的所有字段
            Iterator<Map.Entry<String, JsonNode>> fields = oldNode.fields();

            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> entry = fields.next();
                String fieldName = entry.getKey();
                JsonNode oldFieldValue = entry.getValue();
                JsonNode newFieldValue = newNode.get(fieldName);

                // 如果 newNode 中的字段值不同或不存在于 oldNode 中，将此字段添加到结果 JSON 中
                if (newFieldValue == null || !oldFieldValue.equals(newFieldValue)) {
                    ObjectNode diffNode = resultNode.putObject(fieldName);
                    diffNode.set("old", oldFieldValue);
                    diffNode.set("new", newFieldValue);
                }
            }

            // 迭代 newNode 中的所有字段，检查是否有字段存在于 newNode 中但不存在于 oldNode 中
            fields = newNode.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> entry = fields.next();
                String fieldName = entry.getKey();
                if (!oldNode.has(fieldName)) {
                    ObjectNode diffNode = resultNode.putObject(fieldName);
                    diffNode.set("old", null);
                    diffNode.set("new", entry.getValue());
                }
            }
        } else if (!oldNode.equals(newNode)) {
            // 如果两个节点值不同且不是对象类型，将 newNode 直接作为差异结果
            ObjectNode diffNode = resultNode.putObject("value");
            diffNode.set("old", oldNode);
            diffNode.set("new", newNode);
        }

        return resultNode; // 返回差异结果
    }
}
